/* ************************************************************************ */
/*																			*/
/*  haXe Media 																*/
/*  Copyright (c)2008 Russell Weir damonsbane/gmail dot com					*/
/*																			*/
/* This library is free software; you can redistribute it and/or			*/
/* modify it under the terms of the GNU Lesser General Public				*/
/* License as published by the Free Software Foundation; either				*/
/* version 2.1 of the License, or (at your option) any later version.		*/
/*																			*/
/* This library is distributed in the hope that it will be useful,			*/
/* but WITHOUT ANY WARRANTY; without even the implied warranty of			*/
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU		*/
/* Lesser General Public License or the LICENSE file for more details.		*/
/*																			*/
/* ************************************************************************ */
package netservices;

// Before attempting to work with a remote shared object, first check for any errors
// using a try..catch..finally statement. Then wait until the sync event is dispatched.
// If you fail to do so, any changes you make to the object locally ? before the sync
// event is dispatched ? may be lost. Flash Player does not dispatch a netStatus event in
// response to a SharedObject.connect() call.

class RemoteSharedObject extends SharedObject {
	public var synced(default, null) : Bool;
	public var nc(default,null) : NetConnection;
	public var updateCount(default, null) : Int;
	public var params(default, null) : String;

	public function new(name, ?pathOrUri, ?secure) {
		super(name, pathOrUri, secure);
		updateCount = 0;
		synced = false;
		persistent = false;
	}

	/**
		Connect to a remote shared object.
	*/
	public function connect(nc:NetConnection, persist:Bool, ?params:String) {
		this.nc = nc;
		this.persistent = persist;
		this.params = params;

		connected = false;
		try {
			so = flash.net.SharedObject.getRemote(name, nc.getObject().uri, persistent);
#if flash9
			so.addEventListener(flash.events.SyncEvent.SYNC, onSync);
			connected = true;
			try {
				so.connect(nc.getObject(), params);
			}
			catch(e:Dynamic) {
				connected = false;
			}
#else flash
			so.onSync = onSync;
			connected = so.connect(nc.nc);
#end
		}
		catch(e:Dynamic) {
		}
		return connected;
	}

	public override function set(key : String, value : Dynamic) : Bool {
		if(!synced || !connected) {
			//trace("SharedObject: Not connected");
			return false;
		}
		so.setProperty(key, value);
		return true;
	}

#if flash9
	function onSync(e : flash.events.SyncEvent) {
#else flash
	function onSync(e : Array<Dynamic>) {
#end
		if(!synced) {
			connected = true;
			synced = true;
		}
		updateCount++;
		// update recieved, broadcast change list
		//e.changeList [{name:[varname], code:[success|reject]},{},...]
#if flash9
		events.onSync.call(e.changeList);
		for(i in e.changeList) {
#else flash
		events.onSync.call(e);
		for(i in e) {
#end
			// broadcast individual var success/failure
			if(untyped i.code == "change") {
				events.onSyncChange.call(Std.string(untyped i.name), untyped i.oldValue);
			}
			else if(untyped i.code == "reject") {
				events.onSyncReject.call(Std.string(untyped i.name), untyped i.oldValue);
			}
			else if(untyped i.code == "success") {
				events.onSyncSuccess.call(Std.string(untyped i.name));
			}
		}
	}
}